<?php

namespace App\Modules\GrpcApi\Service\Impls;

use App\Components\Log;
use App\Modules\GrpcApi\Service\ApiService;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\RequestOptions;
use Hyperf\Di\Annotation\Inject;

class ApiServiceImpl implements ApiService
{

    /**
     * @var array|mixed
     */
    protected array $config;

    /**
     * @var Client
     * @Inject
     */
    protected Client $client;

    public function __construct()
    {
        $this->config = config('api_config.gci_api');
    }

    /**
     * @param string $start
     * @param string $end
     * @param string $city
     * @return array
     * @throws GuzzleException
     */
    public function getBusLine(string $start, string $end, string $city): array
    {
        $this->client = new Client();
        try {
            // 获取出发、到达地的经纬度 默认第一个是起始站
            $startLocation = $this->getPois($start, $city);
            $endLocation = $this->getPois($end, $city);
            if (empty($startLocation) || empty($endLocation)) {
                return [];
            }
            $url = $this->config['amap']['uri'] . '/direction/transit/integrated';
            $params = [
                'key' => $this->config['amap']['key'],
                'origin' => $startLocation,
                'destination' => $endLocation,
                'city' => $city,
                'strategy' => 5,
                'extensions' => 'base'
            ];

            Log::info('GCI searchBusLine request data: ', [
                'url' => $url,
                'body' => $params,
            ]);

            $client = new Client();
            $resp = $client->get($url, [
                RequestOptions::QUERY => $params,
            ]);
            $body = $resp->getBody()->getContents();
            Log::info('GCI searchBusLine response data', [
                'headers' => $resp->getHeaders(),
                'body' => $body,
            ]);
            $response = json_decode($body, true);
            $routes = [];
            if ($response['info'] == 'OK' && $response['status'] == 1) {
                if (isset($response['route']) && $response['count'] > 0) {
                    $costLeastTime = current($response['route']['transits'])['duration'];
                    foreach ($response['route']['transits'] as $transit) {
                        if ($transit['duration'] <= $costLeastTime) {
                            $costLeastTime = $transit['duration'];
                            $segments = $transit['segments'];
                            foreach ($segments as $segment) {
                                if (isset($segment['bus']) && !empty($segment['bus']['buslines'])) {
                                    $busLines = $segment['bus']['buslines'];
                                    foreach ($busLines as $busLine) {
//                                        $viaStops = array_column($busLine['via_stops'], 'name');
//                                        array_unshift($viaStops, $busLine['departure_stop']['name']);
//                                        array_push($viaStops, $busLine['arrival_stop']['name']);
                                        $routes[$busLine['name']] = $busLine['arrival_stop']['name'];
                                    }
                                }
                            }
                        }
                    }
                }
            }
            return $routes;
        } catch (\Exception $exception) {
            Log::info('GCI searchBusLine exception:', [
                'msg' => $exception->getMessage(),
                'trace' => $exception->getTrace()
            ]);
            return [];
        }
    }

    /**
     * @param string $station
     * @param string $city
     * @return string
     * @throws GuzzleException
     */
    private function getPois(string $station, string $city): string
    {
        try {
            $url = $this->config['amap']['uri'] . '/place/text';
            $params = [
                'key' => $this->config['amap']['key'],
                'keywords' => $station,
                'city' => $city
            ];
            Log::info('GCI getPois request data: ', [
                'url' => $url,
                'body' => $params,
            ]);

            $resp = $this->client->get($url, [
                RequestOptions::QUERY => $params,
            ]);
            $body = $resp->getBody()->getContents();
            Log::info('GCI getPois response data', [
                'headers' => $resp->getHeaders(),
                'body' => $body,
            ]);
            $response = json_decode($body, true);
            $location = '';
            if ($response['info'] == 'OK' && $response['status'] == 1) {
                if (isset($response['pois']) && !empty($response['pois'])) {
                    // 默认取第一个
                    $location = current($response['pois'])['location'];
                    foreach ($response['pois'] as $pois) {
                        if (strpos($pois['type'], '公交车站') !== false) {
                            $location = $pois['location'];
                            break;
                        }
                    }
                }
            }
            Log::info('GCI getPois result:', [
                'bus_address' => $location
            ]);
            return $location;
        } catch (\Exception $exception) {
            Log::info('GCI getPois exception:', [
                'msg' => $exception->getMessage(),
                'trace' => $exception->getTrace()
            ]);
            return '';
        }
    }
}